#include "../InetAddress.h"
#include "../SocketsOps.h"
#include <string.h>
#include "netinet/in.h"
using namespace yhaida;

static const in_addr_t kInaddrAny = INADDR_ANY;
static_assert(sizeof(InetAddress) == sizeof(struct sockaddr_in));

InetAddress::InetAddress(uint16_t port)
{
    // AF_INET（TCP/IP – IPv4）
    bzero(&_addr, sizeof(_addr));
    _addr.sin_family = AF_INET;
    _addr.sin_addr.s_addr = sockets::hostToNetwork32(kInaddrAny);
    _addr.sin_port = sockets::hostToNetwork16(port);
}
InetAddress::InetAddress(const std::string &ip, uint16_t port)
{
    bzero(&_addr, sizeof(_addr));
    sockets::fromHostPort(ip.c_str(), port, &_addr);
}

std::string InetAddress::toHostPort() const
{
    char buff[32];
    sockets::toHostPort(buff, sizeof(buff), _addr);
    return buff;
}
/*
struct hostent
{
    char *h_name;         //正式主机名
    char **h_aliases;     //主机别名
    int h_addrtype;       //主机IP地址类型：IPV4-AF_INET
    int h_length;         //主机IP地址字节长度，对于IPv4是四字节，即32位
    char **h_addr_list;   //主机的IP地址列表
};
*/
static __thread char t_resolveBuffer[64 * 1024];

bool InetAddress::resolve(std::string hostname, InetAddress *out)
{
    assert(out != NULL);
    struct hostent hent;
    struct hostent *he = NULL;
    int herrno = 0;
    memset(&hent, 0, sizeof(hent));

    int ret = gethostbyname_r(hostname.c_str(), &hent, t_resolveBuffer, sizeof(t_resolveBuffer), &he, &herrno);
    if (ret == 0 && he != NULL)
    {
        assert(he->h_addrtype == AF_INET && he->h_length == sizeof(uint32_t));
        out->_addr.sin_addr = *reinterpret_cast<struct in_addr *>(he->h_addr);
        return true;
    }
    else
    {
        if (ret)
        {
            LOG_SYSERR << "InetAddress::resolve";
        }
        return false;
    }
}

uint32_t InetAddress::ipv4NetEndian() const
{
  assert(family() == AF_INET);
  return _addr.sin_addr.s_addr;
}